import { Injectable, ExecutionContext, CallHandler, HttpException, HttpStatus } from '@nestjs/common'
import { Observable } from 'rxjs'
import { Reflector } from '@nestjs/core' // 用于读取元数据

const requestMap = new Map<string, number[]>()

@Injectable()
export class RateLimitInterceptor {
  // 默认限流规则（未设置装饰器时使用）
  private readonly defaultLimit = 3
  private readonly defaultWindowMs = 60 * 1000

  constructor(private reflector: Reflector) { } // 注入Reflector读取元数据

  async intercept(context: ExecutionContext, next: CallHandler): Promise<Observable<any>> {
    const request = context.switchToHttp().getRequest()

    // 从装饰器获取当前接口的限流规则（优先使用自定义规则）
    const rateLimitOptions = this.reflector.get(
      'rateLimit',
      context.getHandler(), // 获取当前接口的元数据
    ) || {
      limit: this.defaultLimit,
      windowMs: this.defaultWindowMs,
    }
    const { limit, windowMs } = rateLimitOptions

    // 获取用户标识+接口路径（生成唯一键）
    const identifier = this.getIdentifier(request)
    const path = request.path
    const key = `${identifier}:${path}`

    // 清理过期记录
    const now = Date.now()
    const timestamps = requestMap.get(key) || []
    const validTimestamps = timestamps.filter(ts => now - ts < windowMs)

    // 检查是否超过限制
    if (validTimestamps.length >= limit) {
      // const retryAfter = Math.ceil((windowMs - (now - validTimestamps[0])) / 1000)
      throw new HttpException(`请求频繁，请稍后操作`, 429)
    }

    // 记录本次请求
    validTimestamps.push(now)
    requestMap.set(key, validTimestamps)

    return next.handle()
  }

  private getIdentifier(request: any): string {
    return request.user?.id ? `user:${request.user.id}` : `ip:${request.ip || 'unknown'}`
  }
}